package com.zsk.service.impl;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import com.zsk.bean.ColParams;
import com.zsk.bean.TableParams;
import com.zsk.service.IEntityCodeGenService;
import com.zsk.service.IJpaCodeGenService;
import com.zsk.service.IMvnPrjGenService;
import com.zsk.service.IRepositoryCodeGenService;
import com.zsk.service.IServiceCodeGenService;
import com.zsk.util.FileUtil;
import com.zsk.util.MvnPrjUtil;
import com.zsk.util.ZipUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class JpaCodeGenServiceImpl implements IJpaCodeGenService {

    private final static String workingDir = "workspace";

    @Autowired
    private IEntityCodeGenService entityGenSvc;
    @Autowired
    private IRepositoryCodeGenService repositoryGenSvc;
    @Autowired
    private IServiceCodeGenService servicGenSvc;
    @Autowired
    private IMvnPrjGenService mvnGenSvc;

    @Override
    public String genJpaPrj(HttpServletResponse response, List<TableParams> list, String packageName, String groupId,
        String artifactId) {
        String prjDir = MvnPrjUtil.workingDir + "/" + artifactId;
        FileUtil.emptyDir(prjDir);
        entityGenSvc.genEntityCode(list, packageName, groupId, artifactId);
        repositoryGenSvc.genRepositoryCode(list, packageName, groupId, artifactId);
        servicGenSvc.genServiceCode(list, packageName, groupId, artifactId);
        mvnGenSvc.genMvnPrjCode(list, packageName, groupId, artifactId);
        try {
            ZipUtil.toZip(prjDir, new FileOutputStream(prjDir + ".zip"), true);
        } catch (FileNotFoundException | RuntimeException e) {
            log.error(e.toString());
            return "springboot项目生成失败";
        }
        return "springboot项目生成成功";
    }

    @Override
    public String genCode(List<TableParams> list, String packageName, String groupId, String artifactId) {
        FileUtil.deleteDir(workingDir + "/" + artifactId);
        list.forEach(e -> {
            genEntity(e, packageName, artifactId);
            genRepository(e, packageName, artifactId);
            genServiceItf(e, packageName, artifactId);
            genService(e, packageName, artifactId);
        });
        genCommonCode(packageName, artifactId);
        genPomXml(groupId, artifactId);
        return "生成成功";
    }

    @Override
    public String genEntity(TableParams tableInfo, String packageName, String artifactId) {
        String name = "entity";
        String nameExt = "Entity";
        String tableName = tableInfo.getTableName();

        StringBuilder sbCol = new StringBuilder();
        List<ColParams> cols = tableInfo.getTableCol();
        cols.forEach(e -> {
            String type = "String";
            switch (e.getColType()) {
                case "String":
                    type = "String";
                    break;
                case "Integer":
                    type = "Integer";
                    break;
                case "Boolean":
                    type = "Boolean";
                    break;
                case "Date":
                    type = "Date";
                    break;

                default:
                    break;
            }
            sbCol.append("private " + type + " " + e.getColName() + ";\n    ");
        });

        String className = getClassName(tableName);
        StringBuilder sb = FileUtil.readTxtFile("template/EntityTemplate.java");
        String content = sb.toString().replace("#1", packageName + "." + name).replace("#2", className)
            .replace("#3", className + nameExt).replace("#4", sbCol);

        String dir = getCodeDir(artifactId, packageName) + name;
        FileUtil.makeDir(dir);
        FileUtil.writeTxtFile(content, dir + "/" + className + nameExt + ".java");
        return content;

    }

    @Override
    public String genRepository(TableParams tableInfo, String packageName, String artifactId) {
        String name = "repository";
        String nameExt = "Repository";
        String dir = getCodeDir(artifactId, packageName) + name;
        String tableName = tableInfo.getTableName();

        StringBuilder sb = FileUtil.readTxtFile("template/RepositoryTemplate.java");
        String className = getClassName(tableName);
        String colName = tableInfo.getTableCol().get(0).getColName();
        colName = colName.substring(0, 1).toUpperCase() + colName.substring(1);
        String content = sb.toString().replace("#1", packageName + "." + name)
            .replace("#2", packageName + ".entity." + className + "Entity;")
            .replace("#3", className + "Entity" + nameExt).replace("#4", className + "Entity").replace("#5", colName)
            .replace("#6", colName).replace("#7", colName);

        FileUtil.makeDir(dir);
        FileUtil.writeTxtFile(content, dir + "/" + className + "Entity" + nameExt + ".java");
        return content;
    }

    @Override
    public String genServiceItf(TableParams tableInfo, String packageName, String artifactId) {
        String name = "service";
        String nameExt = "Service";
        String dir = getCodeDir(artifactId, packageName) + name;
        String tableName = tableInfo.getTableName();

        StringBuilder sb = FileUtil.readTxtFile("template/IServiceTemplate.java");
        String className = getClassName(tableName);
        String colName = tableInfo.getTableCol().get(0).getColName();
        colName = colName.substring(0, 1).toUpperCase() + colName.substring(1);
        String content =
            sb.toString().replace("#1", packageName + "." + name).replace("#2", packageName + ".bean.ResultBean;")
                .replace("#3", packageName + ".entity." + className + "Entity;")
                .replace("#4", packageName + ".bean.PageBean;").replace("#5", "I" + className + nameExt)
                .replace("#6", className + "Entity");

        FileUtil.makeDir(dir);
        FileUtil.writeTxtFile(content, dir + "/" + "I" + className + nameExt + ".java");
        return content;
    }

    @Override
    public String genService(TableParams tableInfo, String packageName, String artifactId) {
        String dir = getCodeDir(artifactId, packageName) + "service/impl";
        String tableName = tableInfo.getTableName();

        StringBuilder sb = FileUtil.readTxtFile("template/ServiceImplTemplate.java");
        String className = getClassName(tableName);
        String colName = tableInfo.getTableCol().get(0).getColName();
        colName = colName.substring(0, 1).toUpperCase() + colName.substring(1);
        String content = sb.toString().replace("#1", packageName + ".service.impl")
            .replace("#2",
                packageName + ".bean.ResultBean;" + "\nimport " + packageName + ".bean.PageBean;" + "\nimport "
                    + packageName + ".util.JPAUtil;")
            .replace("#3", packageName + ".entity." + className + "Entity;")
            .replace("#4", packageName + ".repository." + className + "EntityRepository;")
            .replace("#5", packageName + ".service." + "I" + className + "Service;")
            .replace("#6", className + "ServiceImpl").replace("#7", "I" + className + "Service")
            .replace("#8", className + "EntityRepository").replace("#9", tableName + "Rep")
            .replace("#a", className + "Entity");

        FileUtil.makeDir(dir);
        FileUtil.writeTxtFile(content, dir + "/" + className + "ServiceImpl" + ".java");
        return content;
    }

    public void genCommonCode(String packageName, String artifactId) {
        String dir = getCodeDir(artifactId, packageName);
        String beanDir = dir + "/bean";
        String utilDir = dir + "/util";

        String pageStr = FileUtil.readTxtFile("template/PageBean.java").toString();
        String resStr = FileUtil.readTxtFile("template/ResultBean.java").toString();
        String jpaUtilStr = FileUtil.readTxtFile("template/JPAUtil.java").toString();

        pageStr = pageStr.replace("#1", packageName + ".bean");
        resStr = resStr.replace("#1", packageName + ".bean");
        jpaUtilStr = jpaUtilStr.replace("#1", packageName + ".util").replace("#2", packageName + "bean.PageBean;");

        FileUtil.makeDir(beanDir);
        FileUtil.makeDir(utilDir);
        FileUtil.writeTxtFile(pageStr, beanDir + "/PageBean.java");
        FileUtil.writeTxtFile(resStr, beanDir + "/ResultBean.java");
        FileUtil.writeTxtFile(jpaUtilStr, dir + "/util/JPAUtil.java");
    }

    public void genPomXml(String groupId, String artifactId) {
        String dir = workingDir + "/" + artifactId;
        String pom = FileUtil.readTxtFile("template/pom.xml").toString();
        pom = pom.replace("#1", groupId).replace("#2", artifactId);
        FileUtil.writeTxtFile(pom, dir + "/pom.xml");
        try {
            String resDir = dir + "/src/main/resources";
            FileUtil.makeDir(resDir);
            FileCopyUtils.copy(FileUtils.getFile("template/application.yml"),
                FileUtils.getFile(resDir + "/application.yml"));
        } catch (IOException e) {
            log.error(e.toString());
        }
    }

    public String getClassName(String tableName) {
        String first = tableName.substring(0, 1);
        String after = tableName.substring(1);
        first = first.toUpperCase();
        return first + after;
    }

    public String getCodeDir(String artifactId, String packageName) {
        return workingDir + "/" + artifactId + "/src/main/java/" + packageName.replaceAll("\\.", "/") + "/";
    }

    public static void main(String[] args) {
        TableParams tableParams = new TableParams();
        tableParams.setTableName("demoInfo");
        List<ColParams> cols = new ArrayList<ColParams>();
        cols.add(new ColParams("userName", "String"));
        cols.add(new ColParams("age", "Integer"));
        tableParams.setTableCol(cols);

        // String aId = "gen-code-prj";
        // String gid = "com.zsk.boot";
        // String p = "com.zsk";
        // genEntity(tableParams, p, aId);
        // genRepository(tableParams, p, aId);
        // genServiceItf(tableParams, p, aId);
        // genService(tableParams, p, aId);
        // genCommonCode(p, aId);
        // genPomXml(gid, aId);
    }

}
